package com.rickpan.service;

import com.rickpan.entity.TeamMessage;
import com.rickpan.entity.User;
import com.rickpan.repository.TeamMessageRepository;
import com.rickpan.repository.UserRepository;
import com.rickpan.dto.request.TeamMessageRequest;
import com.rickpan.dto.response.TeamMessageDTO;
import com.rickpan.exception.BusinessException;

import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 团队消息服务类
 * 
 * @author 开发团队协调员
 * @since 2025-07-16
 */
@Service
@Transactional
public class TeamMessageService {

    private static final Logger logger = LoggerFactory.getLogger(TeamMessageService.class);
    
    // 消息内容最大长度限制
    private static final int MAX_CONTENT_LENGTH = 4000;
    
    // 默认分页大小
    private static final int DEFAULT_PAGE_SIZE = 20;

    @Autowired
    private TeamMessageRepository teamMessageRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private TeamMemberService teamMemberService;

    /**
     * 发送团队消息
     * 
     * @param request 消息请求
     * @param senderId 发送者ID
     * @return 消息DTO
     */
    public TeamMessageDTO sendMessage(TeamMessageRequest request, Long senderId) {
        logger.info("发送团队消息 teamId={}, senderId={}, type={}", 
                   request.getTeamId(), senderId, request.getMessageType());

        // 验证消息内容
        validateMessageContent(request);

        // 验证用户权限
        if (!teamMemberService.isTeamMember(request.getTeamId(), senderId)) {
            throw new BusinessException("您不是该团队成员，无法发送消息");
        }

        // 创建消息实体
        TeamMessage message = new TeamMessage();
        message.setTeamId(request.getTeamId());
        message.setSenderId(senderId);
        message.setMessageType(TeamMessage.MessageType.valueOf(request.getMessageType()));
        message.setContent(request.getContent());
        message.setMessageStatus(TeamMessage.MessageStatus.sent);

        // 处理文件消息
        if ("file".equals(request.getMessageType()) || "image".equals(request.getMessageType())) {
            message.setFileName(request.getFileName());
            message.setFileSize(request.getFileSize());
            message.setFileUrl(request.getFileUrl());
        }

        // 处理回复消息
        if (request.getReplyToId() != null) {
            message.setReplyToId(request.getReplyToId());
        }

        // 保存消息
        TeamMessage savedMessage = teamMessageRepository.save(message);

        // 转换为DTO并返回
        return convertToDTO(savedMessage);
    }

    /**
     * 获取团队消息历史（分页）
     * 
     * @param teamId 团队ID
     * @param userId 用户ID（用于权限验证）
     * @param page 页码（从0开始）
     * @param size 每页大小
     * @return 分页消息列表
     */
    @Transactional(readOnly = true)
    public Page<TeamMessageDTO> getTeamMessages(Long teamId, Long userId, int page, int size) {
        logger.info("获取团队消息历史 teamId={}, userId={}, page={}, size={}", 
                   teamId, userId, page, size);

        // 验证用户权限
        if (!teamMemberService.isTeamMember(teamId, userId)) {
            throw new BusinessException("您不是该团队成员，无法查看消息");
        }

        // 限制分页大小
        if (size > 100) {
            size = 100;
        }
        if (size <= 0) {
            size = DEFAULT_PAGE_SIZE;
        }

        Pageable pageable = PageRequest.of(page, size);
        Page<TeamMessage> messagePage = teamMessageRepository.findByTeamIdOrderByCreatedAtDesc(teamId, pageable);

        return messagePage.map(this::convertToDTO);
    }

    /**
     * 获取团队最近消息
     * 
     * @param teamId 团队ID
     * @param userId 用户ID（用于权限验证）
     * @param limit 限制数量
     * @return 最近消息列表
     */
    @Transactional(readOnly = true)
    public List<TeamMessageDTO> getRecentMessages(Long teamId, Long userId, int limit) {
        logger.info("获取团队最近消息 teamId={}, userId={}, limit={}", teamId, userId, limit);

        // 验证用户权限
        if (!teamMemberService.isTeamMember(teamId, userId)) {
            throw new BusinessException("您不是该团队成员，无法查看消息");
        }

        // 限制查询数量
        if (limit > 50) {
            limit = 50;
        }
        if (limit <= 0) {
            limit = 10;
        }

        List<TeamMessage> messages = teamMessageRepository.findRecentMessagesByTeamId(teamId, limit);
        return messages.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    /**
     * 更新消息状态
     * 
     * @param messageId 消息ID
     * @param status 新状态
     * @param userId 操作用户ID
     */
    public void updateMessageStatus(Long messageId, TeamMessage.MessageStatus status, Long userId) {
        logger.info("更新消息状态 messageId={}, status={}, userId={}", messageId, status, userId);

        TeamMessage message = teamMessageRepository.findById(messageId)
                .orElseThrow(() -> new BusinessException("消息不存在"));

        // 验证权限（只有发送者可以更新消息状态）
        if (!message.getSenderId().equals(userId)) {
            throw new BusinessException("您只能更新自己发送的消息状态");
        }

        message.setMessageStatus(status);
        teamMessageRepository.save(message);
    }

    /**
     * 搜索团队消息
     * 
     * @param teamId 团队ID
     * @param userId 用户ID（用于权限验证）
     * @param keyword 关键词
     * @param page 页码
     * @param size 每页大小
     * @return 搜索结果
     */
    @Transactional(readOnly = true)
    public Page<TeamMessageDTO> searchMessages(Long teamId, Long userId, String keyword, int page, int size) {
        logger.info("搜索团队消息 teamId={}, userId={}, keyword={}", teamId, userId, keyword);

        // 验证用户权限
        if (!teamMemberService.isTeamMember(teamId, userId)) {
            throw new BusinessException("您不是该团队成员，无法搜索消息");
        }

        if (keyword == null || keyword.trim().isEmpty()) {
            throw new BusinessException("搜索关键词不能为空");
        }

        Pageable pageable = PageRequest.of(page, size);
        Page<TeamMessage> messagePage = teamMessageRepository.searchMessagesByKeyword(teamId, keyword.trim(), pageable);

        return messagePage.map(this::convertToDTO);
    }

    /**
     * 获取消息统计信息
     * 
     * @param teamId 团队ID
     * @param userId 用户ID（用于权限验证）
     * @return 统计信息
     */
    @Transactional(readOnly = true)
    public Object getMessageStatistics(Long teamId, Long userId) {
        logger.info("获取消息统计 teamId={}, userId={}", teamId, userId);

        // 验证用户权限
        if (!teamMemberService.isTeamMember(teamId, userId)) {
            throw new BusinessException("您不是该团队成员，无法查看统计信息");
        }

        long totalCount = teamMessageRepository.countByTeamId(teamId);
        List<Object[]> typeStats = teamMessageRepository.countMessagesByType(teamId);

        return Map.of(
            "totalCount", totalCount,
            "typeStatistics", typeStats
        );
    }

    /**
     * 验证消息内容
     */
    private void validateMessageContent(TeamMessageRequest request) {
        if (request.getContent() == null || request.getContent().trim().isEmpty()) {
            throw new BusinessException("消息内容不能为空");
        }

        if (request.getContent().length() > MAX_CONTENT_LENGTH) {
            throw new BusinessException("消息内容长度不能超过" + MAX_CONTENT_LENGTH + "字符");
        }

        // 验证消息类型
        try {
            TeamMessage.MessageType.valueOf(request.getMessageType());
        } catch (IllegalArgumentException e) {
            throw new BusinessException("不支持的消息类型: " + request.getMessageType());
        }
    }

    /**
     * 转换消息实体为DTO
     */
    private TeamMessageDTO convertToDTO(TeamMessage message) {
        TeamMessageDTO dto = new TeamMessageDTO();
        dto.setId(message.getId());
        dto.setTeamId(message.getTeamId());
        dto.setSenderId(message.getSenderId());
        dto.setMessageType(message.getMessageType().name());
        dto.setContent(message.getContent());
        dto.setFileName(message.getFileName());
        dto.setFileSize(message.getFileSize());
        dto.setFileUrl(message.getFileUrl());
        dto.setMessageStatus(message.getMessageStatus().name());
        dto.setReplyToId(message.getReplyToId());
        dto.setTimestamp(message.getCreatedAt().toEpochSecond(java.time.ZoneOffset.UTC) * 1000);

        // 设置加密相关字段
        dto.setIv(message.getIv());
        dto.setEncryptionAlgorithm(message.getEncryptionAlgorithm());
        dto.setKeyVersion(message.getKeyVersion());
        dto.setIsEncrypted(message.getIsEncrypted());

        // 获取发送者信息
        User sender = userRepository.findById(message.getSenderId()).orElse(null);
        if (sender != null) {
            dto.setSenderName(sender.getUsername());
            dto.setSenderAvatar(sender.getAvatarUrl());
        }

        return dto;
    }
}
